income <- read.csv("D:/OneDrive - West Chester University of PA/Documents/Spring'22/STA553-DataViz/git/Datasets/income_per_person.csv")
pop <- read.csv("D:/OneDrive - West Chester University of PA/Documents/Spring'22/STA553-DataViz/git/Datasets/population_total.csv")
life <- read.csv("D:/OneDrive - West Chester University of PA/Documents/Spring'22/STA553-DataViz/git/Datasets/life_expectancy_years.csv")
countries <- read.csv("D:/OneDrive - West Chester University of PA/Documents/Spring'22/STA553-DataViz/git/Datasets/countries_total.csv")

income.new <- income %>%
  gather(key = "Year", value = "Income", -geo, na.rm=TRUE) %>%
  mutate(Country = geo, Year = substr(Year,2,5)) %>%
  select(-geo)

life.new <- life %>%
  gather(key = "Year", value = "Life", -geo, na.rm=TRUE) %>%
  mutate(Country = geo, Year = substr(Year,2,5)) %>%
  select(-geo)
life.new

pop.new <- pop %>%
  gather(key = "Year", value = "pop", -geo, na.rm=TRUE) %>%
  mutate(Country = geo, Year = substr(Year,2,5)) %>%
  select(-geo)
pop.new

LifeExpIncom <- merge(income.new, life.new, by = c("Country","Year"))
LifeIncomCoun <- merge(LifeExpIncom, countries, by.x = "Country", by.y = "name")
LifeIncomCoun <- select(LifeIncomCoun, Year, Country, region, Income, Life)
final.data <- merge(LifeIncomCoun, pop.new, by = c("Country","Year"))

comp1 <- filter(final.data, Year == 2015)

plot_ly(
  data = comp1,
  x = ~Income,  # Horizontal axis 
  y = ~Life,   # Vertical axis 
  color = ~Country,  # must be a numeric factor
  size = ~pop,
  type = "scatter",
  mode = "markers",
  text = ~Country,
  alpha = 0.6,
  hovertemplate = paste("<b>Income: %{x:$,}</b>",
                          "<br><b>Life: %{y:,}</b>",
                          "<br><b>Population: %{marker.size:,.0f}</b>",
                          '<br><b> %{text}</b>'))
Warning in RColorBrewer::brewer.pal(N, "Set2") :
  n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors

Warning in RColorBrewer::brewer.pal(N, "Set2") :
  n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors

Warning in RColorBrewer::brewer.pal(N, "Set2") :
  n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors

Warning in RColorBrewer::brewer.pal(N, "Set2") :
  n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
p <- ggplot(data = final.data, mapping = aes(x = Income,
                                             y = Life,
                                             size = pop,
                                             color = Country
                                             )) +
  geom_point(alpha = 0.5, show.legend = FALSE) +
  scale_color_viridis_d() +      # color pallets 
  scale_size(range = c(2, 12)) +
  scale_x_log10() +
  labs(title = 'Year: {frame_time}',
       x = 'Income',
       y = 'life expectancy') +
  transition_time(Year) +
  ease_aes('linear')

animate(p, renderer = gifski_renderer(),
          rewind = TRUE)

Rendering [>------------------------------------------------------] at 3.9 fps ~ eta: 13s
Rendering [=>-----------------------------------------------------] at 3.6 fps ~ eta: 13s
Rendering [==>----------------------------------------------------] at 3.4 fps ~ eta: 14s
Rendering [===>---------------------------------------------------] at 3.1 fps ~ eta: 15s
Rendering [=====>-------------------------------------------------] at 3.1 fps ~ eta: 15s
Rendering [======>--------------------------------------------------] at 3 fps ~ eta: 14s
Rendering [=======>-----------------------------------------------] at 3.1 fps ~ eta: 14s
Rendering [========>----------------------------------------------] at 3.1 fps ~ eta: 13s
Rendering [=========>---------------------------------------------] at 3.1 fps ~ eta: 13s
Rendering [==========>--------------------------------------------] at 3.1 fps ~ eta: 13s
Rendering [===========>-------------------------------------------] at 3.1 fps ~ eta: 12s
Rendering [============>------------------------------------------] at 3.1 fps ~ eta: 12s
Rendering [=============>-----------------------------------------] at 3.1 fps ~ eta: 12s
Rendering [==============>----------------------------------------] at 3.1 fps ~ eta: 12s
Rendering [===============>---------------------------------------] at 3.1 fps ~ eta: 11s
Rendering [=================>-------------------------------------] at 3.1 fps ~ eta: 11s
Rendering [==================>------------------------------------] at 3.1 fps ~ eta: 11s
Rendering [===================>-----------------------------------] at 3.1 fps ~ eta: 10s
Rendering [====================>----------------------------------] at 3.1 fps ~ eta: 10s
Rendering [=====================>---------------------------------] at 3.1 fps ~ eta: 10s
Rendering [======================>--------------------------------] at 3.1 fps ~ eta:  9s
Rendering [=======================>-------------------------------] at 3.1 fps ~ eta:  9s
Rendering [========================>------------------------------] at 3.1 fps ~ eta:  9s
Rendering [=========================>-----------------------------] at 3.1 fps ~ eta:  8s
Rendering [===========================>---------------------------] at 3.1 fps ~ eta:  8s
Rendering [============================>--------------------------] at 3.1 fps ~ eta:  8s
Rendering [=============================>-------------------------] at 3.1 fps ~ eta:  7s
Rendering [==============================>------------------------] at 3.1 fps ~ eta:  7s
Rendering [===============================>-----------------------] at 3.1 fps ~ eta:  7s
Rendering [================================>----------------------] at 3.1 fps ~ eta:  7s
Rendering [==================================>----------------------] at 3 fps ~ eta:  6s
Rendering [===================================>---------------------] at 3 fps ~ eta:  6s
Rendering [=====================================>-------------------] at 3 fps ~ eta:  6s
Rendering [======================================>------------------] at 3 fps ~ eta:  5s
Rendering [=======================================>-----------------] at 3 fps ~ eta:  5s
Rendering [========================================>----------------] at 3 fps ~ eta:  5s
Rendering [=========================================>---------------] at 3 fps ~ eta:  4s
Rendering [==========================================>--------------] at 3 fps ~ eta:  4s
Rendering [===========================================>-------------] at 3 fps ~ eta:  4s
Rendering [=============================================>-----------] at 3 fps ~ eta:  3s
Rendering [==============================================>----------] at 3 fps ~ eta:  3s
Rendering [===============================================>---------] at 3 fps ~ eta:  3s
Rendering [================================================>--------] at 3 fps ~ eta:  2s
Rendering [=================================================>-------] at 3 fps ~ eta:  2s
Rendering [==================================================>------] at 3 fps ~ eta:  2s
Rendering [===================================================>-----] at 3 fps ~ eta:  1s
Rendering [=====================================================>---] at 3 fps ~ eta:  1s
Rendering [====================================================>--] at 2.9 fps ~ eta:  1s
Rendering [=====================================================>-] at 2.9 fps ~ eta:  0s
Rendering [=======================================================] at 2.9 fps ~ eta:  0s
                                                                                         


Inserting image 1 at 0.00s (1%)...
Inserting image 2 at 0.10s (2%)...
Inserting image 3 at 0.20s (3%)...
Inserting image 4 at 0.30s (4%)...
Inserting image 5 at 0.40s (5%)...
Inserting image 6 at 0.50s (6%)...
Inserting image 7 at 0.60s (7%)...
Inserting image 8 at 0.70s (8%)...
Inserting image 9 at 0.80s (9%)...
Inserting image 10 at 0.90s (10%)...
Inserting image 11 at 1.00s (11%)...
Inserting image 12 at 1.10s (12%)...
Inserting image 13 at 1.20s (13%)...
Inserting image 14 at 1.30s (14%)...
Inserting image 15 at 1.40s (15%)...
Inserting image 16 at 1.50s (16%)...
Inserting image 17 at 1.60s (17%)...
Inserting image 18 at 1.70s (18%)...
Inserting image 19 at 1.80s (19%)...
Inserting image 20 at 1.90s (20%)...
Inserting image 21 at 2.00s (21%)...
Inserting image 22 at 2.10s (22%)...
Inserting image 23 at 2.20s (23%)...
Inserting image 24 at 2.30s (24%)...
Inserting image 25 at 2.40s (25%)...
Inserting image 26 at 2.50s (26%)...
Inserting image 27 at 2.60s (27%)...
Inserting image 28 at 2.70s (28%)...
Inserting image 29 at 2.80s (29%)...
Inserting image 30 at 2.90s (30%)...
Inserting image 31 at 3.00s (31%)...
Inserting image 32 at 3.10s (32%)...
Inserting image 33 at 3.20s (33%)...
Inserting image 34 at 3.30s (34%)...
Inserting image 35 at 3.40s (35%)...
Inserting image 36 at 3.50s (36%)...
Inserting image 37 at 3.60s (37%)...
Inserting image 38 at 3.70s (38%)...
Inserting image 39 at 3.80s (39%)...
Inserting image 40 at 3.90s (40%)...
Inserting image 41 at 4.00s (41%)...
Inserting image 42 at 4.10s (42%)...
Inserting image 43 at 4.20s (43%)...
Inserting image 44 at 4.30s (44%)...
Inserting image 45 at 4.40s (45%)...
Inserting image 46 at 4.50s (46%)...
Inserting image 47 at 4.60s (47%)...
Inserting image 48 at 4.70s (48%)...
Inserting image 49 at 4.80s (49%)...
Inserting image 50 at 4.90s (50%)...
Inserting image 51 at 5.00s (51%)...
Inserting image 52 at 5.10s (52%)...
Inserting image 53 at 5.20s (53%)...
Inserting image 54 at 5.30s (54%)...
Inserting image 55 at 5.40s (55%)...
Inserting image 56 at 5.50s (56%)...
Inserting image 57 at 5.60s (57%)...
Inserting image 58 at 5.70s (58%)...
Inserting image 59 at 5.80s (59%)...
Inserting image 60 at 5.90s (60%)...
Inserting image 61 at 6.00s (61%)...
Inserting image 62 at 6.10s (62%)...
Inserting image 63 at 6.20s (63%)...
Inserting image 64 at 6.30s (64%)...
Inserting image 65 at 6.40s (65%)...
Inserting image 66 at 6.50s (66%)...
Inserting image 67 at 6.60s (67%)...
Inserting image 68 at 6.70s (68%)...
Inserting image 69 at 6.80s (69%)...
Inserting image 70 at 6.90s (70%)...
Inserting image 71 at 7.00s (71%)...
Inserting image 72 at 7.10s (72%)...
Inserting image 73 at 7.20s (73%)...
Inserting image 74 at 7.30s (74%)...
Inserting image 75 at 7.40s (75%)...
Inserting image 76 at 7.50s (76%)...
Inserting image 77 at 7.60s (77%)...
Inserting image 78 at 7.70s (78%)...
Inserting image 79 at 7.80s (79%)...
Inserting image 80 at 7.90s (80%)...
Inserting image 81 at 8.00s (81%)...
Inserting image 82 at 8.10s (82%)...
Inserting image 83 at 8.20s (83%)...
Inserting image 84 at 8.30s (84%)...
Inserting image 85 at 8.40s (85%)...
Inserting image 86 at 8.50s (86%)...
Inserting image 87 at 8.60s (87%)...
Inserting image 88 at 8.70s (88%)...
Inserting image 89 at 8.80s (89%)...
Inserting image 90 at 8.90s (90%)...
Inserting image 91 at 9.00s (91%)...
Inserting image 92 at 9.10s (92%)...
Inserting image 93 at 9.20s (93%)...
Inserting image 94 at 9.30s (94%)...
Inserting image 95 at 9.40s (95%)...
Inserting image 96 at 9.50s (96%)...
Inserting image 97 at 9.60s (97%)...
Inserting image 98 at 9.70s (98%)...
Inserting image 99 at 9.80s (99%)...
Inserting image 100 at 9.90s (100%)...
Encoding to gif... done!

0.1 comp3


borders <- list(color = toRGB("red"))
g <- list(      scope = 'usa',
           projection = list(type = 'albers usa'),
             showland = TRUE,
            landcolor = toRGB("gray95"),
         subunitcolor = toRGB("gray85"),
         countrycolor = toRGB("Red"),
         countrywidth = 2.5,
         subunitwidth = 5.5
       )
###
fig <- plot_geo(df3, x = ~xcoord, y = ~ycoord) %>% 
  add_markers( text = ~paste(X, paste("State: ",STATE), paste("County: ",county),
                             paste("Address: ",ADDRESS), paste("ZIP code: ",ZIPnew),
                             #paste("Arrivals:", cnt), 
                             sep = "<br>"),
              color = ~description, 
              symbol = "circle", 
              size = ~ZIPPOC, 
              hoverinfo = "text")   %>% 
  colorbar(title = "Urban/Rural<br>2")  %>%
  marker = list(line = borders) %>%
  layout( title = 'Urban/Rural Gas Stations in the US', 
          geo = g )
Error in UseMethod("layout") : 
  no applicable method for 'layout' applied to an object of class "list"
result <- unsplit(df.list, f = df$STATE, drop = TRUE)
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning in x[i] <- value[[j]] :
  number of items to replace is not a multiple of replacement length
Warning: non-unique values when setting 'row.names': ‘10156’, ‘10246’, ‘10272’, ‘10289’, ‘10667’, ‘10764’, ‘11052’, ‘11463’, ‘11485’, ‘11761’, ‘11882’, ‘11897’, ‘1241’, ‘12472’, ‘12503’, ‘12515’, ‘13258’, ‘13265’, ‘13393’, ‘13540’, ‘13608’, ‘1378’, ‘14125’, ‘14265’, ‘14285’, ‘14327’, ‘14372’, ‘14412’, ‘14461’, ‘14562’, ‘14644’, ‘14707’, ‘14973’, ‘15274’, ‘15703’, ‘15705’, ‘1582’, ‘15916’, ‘16151’, ‘16175’, ‘16190’, ‘16299’, ‘1637’, ‘16537’, ‘16577’, ‘16811’, ‘16823’, ‘16962’, ‘16970’, ‘16971’, ‘17021’, ‘17186’, ‘17243’, ‘17336’, ‘17491’, ‘1751’, ‘17797’, ‘17812’, ‘17840’, ‘17861’, ‘17946’, ‘18091’, ‘18546’, ‘1856’, ‘18822’, ‘19004’, ‘19049’, ‘19119’, ‘19123’, ‘19308’, ‘19399’, ‘19526’, ‘19584’, ‘19681’, ‘1985’, ‘19972’, ‘19998’, ‘20775’, ‘20831’, ‘20875’, ‘21251’, ‘21352’, ‘2136’, ‘21608’, ‘21693’, ‘2193’, ‘2198’, ‘2202’, ‘2204’, ‘22073’, ‘22175’, ‘22212’, ‘22322’, ‘22393’, ‘22579’, ‘22804’, ‘22815’, ‘22946’, ‘22989’, ‘23049’, ‘23209’, ‘23530’, ‘23901’, ‘24593’, ‘24726’, ‘24739’, ‘24753’, ‘2521 [... truncated]
Error in `.rowNamesDF<-`(x, value = value) : 
  duplicate 'row.names' are not allowed
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQtMyINCmF1dGhvcjogIlNhaSBWaWduZXNoIFJlZGR5IENob2xsZXRpIg0KZGF0ZTogIjAzLzExLzIwMjIiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoNCmRpdiNUT0MgbGkgew0KICAgIGxpc3Qtc3R5bGU6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQp9DQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogMjRweDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIycHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNXB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCjwvc3R5bGU+DQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiAgIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb3dwbG90IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNvd3Bsb3QiKQ0KICAgbGlicmFyeShjb3dwbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJsYXRleDJleHAiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibGF0ZXgyZXhwIikNCiAgIGxpYnJhcnkobGF0ZXgyZXhwKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikNCiAgIGxpYnJhcnkocGxvdGx5KQ0KfQ0KaWYgKCFyZXF1aXJlKCJnYXBtaW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2FwbWluZGVyIikNCiAgIGxpYnJhcnkoZ2FwbWluZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbmciKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInBuZyIpICAgICAgICAgICAgICMgSW5zdGFsbCBwbmcgcGFja2FnZQ0KICAgIGxpYnJhcnkoInBuZyIpDQp9DQppZiAoIXJlcXVpcmUoIlJDdXJsIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJSQ3VybCIpICAgICAgICAgICAgICMgSW5zdGFsbCBSQ3VybCBwYWNrYWdlDQogICAgbGlicmFyeSgiUkN1cmwiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb2xvdXJwaWNrZXIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImNvbG91cnBpY2tlciIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJjb2xvdXJwaWNrZXIiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ2FuaW1hdGUiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdnYW5pbWF0ZSIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ2FuaW1hdGUiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnaWZza2kiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdpZnNraSIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnaWZza2kiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJtYWdpY2siKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoIm1hZ2ljayIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJtYWdpY2siKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnckRldmljZXMiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdyRGV2aWNlcyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnckRldmljZXMiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJqcGVnIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJqcGVnIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImpwZWciKQ0KfQ0KIyBrbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9ICJDOi9Vc2Vycy83NUNQRU5HL09uZURyaXZlIC0gV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgb2YgUEEvRG9jdW1lbnRzIikNCiMga25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSAiQzpcXFNUQTQ5MFxcdzA1IikNCiMjDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBUUlVFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSkNCmBgYA0KDQpgYGB7cn0NCmluY29tZSA8LSByZWFkLmNzdigiRDovT25lRHJpdmUgLSBXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSBvZiBQQS9Eb2N1bWVudHMvU3ByaW5nJzIyL1NUQTU1My1EYXRhVml6L2dpdC9EYXRhc2V0cy9pbmNvbWVfcGVyX3BlcnNvbi5jc3YiKQ0KcG9wIDwtIHJlYWQuY3N2KCJEOi9PbmVEcml2ZSAtIFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBBL0RvY3VtZW50cy9TcHJpbmcnMjIvU1RBNTUzLURhdGFWaXovZ2l0L0RhdGFzZXRzL3BvcHVsYXRpb25fdG90YWwuY3N2IikNCmxpZmUgPC0gcmVhZC5jc3YoIkQ6L09uZURyaXZlIC0gV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgb2YgUEEvRG9jdW1lbnRzL1NwcmluZycyMi9TVEE1NTMtRGF0YVZpei9naXQvRGF0YXNldHMvbGlmZV9leHBlY3RhbmN5X3llYXJzLmNzdiIpDQpjb3VudHJpZXMgPC0gcmVhZC5jc3YoIkQ6L09uZURyaXZlIC0gV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgb2YgUEEvRG9jdW1lbnRzL1NwcmluZycyMi9TVEE1NTMtRGF0YVZpei9naXQvRGF0YXNldHMvY291bnRyaWVzX3RvdGFsLmNzdiIpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQppbmNvbWUubmV3IDwtIGluY29tZSAlPiUNCiAgZ2F0aGVyKGtleSA9ICJZZWFyIiwgdmFsdWUgPSAiSW5jb21lIiwgLWdlbywgbmEucm09VFJVRSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gZ2VvLCBZZWFyID0gc3Vic3RyKFllYXIsMiw1KSkgJT4lDQogIHNlbGVjdCgtZ2VvKQ0KDQpsaWZlLm5ldyA8LSBsaWZlICU+JQ0KICBnYXRoZXIoa2V5ID0gIlllYXIiLCB2YWx1ZSA9ICJMaWZlIiwgLWdlbywgbmEucm09VFJVRSkgJT4lDQogIG11dGF0ZShDb3VudHJ5ID0gZ2VvLCBZZWFyID0gc3Vic3RyKFllYXIsMiw1KSkgJT4lDQogIHNlbGVjdCgtZ2VvKQ0KbGlmZS5uZXcNCg0KcG9wLm5ldyA8LSBwb3AgJT4lDQogIGdhdGhlcihrZXkgPSAiWWVhciIsIHZhbHVlID0gInBvcCIsIC1nZW8sIG5hLnJtPVRSVUUpICU+JQ0KICBtdXRhdGUoQ291bnRyeSA9IGdlbywgWWVhciA9IHN1YnN0cihZZWFyLDIsNSkpICU+JQ0KICBzZWxlY3QoLWdlbykNCnBvcC5uZXcNCg0KTGlmZUV4cEluY29tIDwtIG1lcmdlKGluY29tZS5uZXcsIGxpZmUubmV3LCBieSA9IGMoIkNvdW50cnkiLCJZZWFyIikpDQpMaWZlSW5jb21Db3VuIDwtIG1lcmdlKExpZmVFeHBJbmNvbSwgY291bnRyaWVzLCBieS54ID0gIkNvdW50cnkiLCBieS55ID0gIm5hbWUiKQ0KTGlmZUluY29tQ291biA8LSBzZWxlY3QoTGlmZUluY29tQ291biwgWWVhciwgQ291bnRyeSwgcmVnaW9uLCBJbmNvbWUsIExpZmUpDQpmaW5hbC5kYXRhIDwtIG1lcmdlKExpZmVJbmNvbUNvdW4sIHBvcC5uZXcsIGJ5ID0gYygiQ291bnRyeSIsIlllYXIiKSkNCg0KY29tcDEgPC0gZmlsdGVyKGZpbmFsLmRhdGEsIFllYXIgPT0gMjAxNSkNCmBgYA0KDQoNCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQoNCg0KcGxvdF9seSgNCiAgZGF0YSA9IGNvbXAxLA0KICB4ID0gfkluY29tZSwgICMgSG9yaXpvbnRhbCBheGlzIA0KICB5ID0gfkxpZmUsICAgIyBWZXJ0aWNhbCBheGlzIA0KICBjb2xvciA9IH5Db3VudHJ5LCAgIyBtdXN0IGJlIGEgbnVtZXJpYyBmYWN0b3INCiAgc2l6ZSA9IH5wb3AsDQogIHR5cGUgPSAic2NhdHRlciIsDQogIG1vZGUgPSAibWFya2VycyIsDQogIHRleHQgPSB+Q291bnRyeSwNCiAgYWxwaGEgPSAwLjYsDQogIGhvdmVydGVtcGxhdGUgPSBwYXN0ZSgiPGI+SW5jb21lOiAle3g6JCx9PC9iPiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+PGI+TGlmZTogJXt5Oix9PC9iPiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+PGI+UG9wdWxhdGlvbjogJXttYXJrZXIuc2l6ZTosLjBmfTwvYj4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPjxiPiAle3RleHR9PC9iPicpKQ0KDQoNCg0KYGBgDQoNCg0KDQoNCg0KYGBge3J9DQpsaWJyYXJ5KGdhcG1pbmRlcikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KDQpybShjb3VudHJpZXMsIGluY29tZSxpbmNvbWUubmV3LCBsaWZlLCBsaWZlLm5ldyxMaWZlRXhwSW5jb20sTGlmZUluY29tQ291bixwb3AsIHBvcC5uZXcpDQpmaW5hbC5kYXRhJFllYXIgPC0gYXMubnVtZXJpYyhmaW5hbC5kYXRhJFllYXIpDQpjb21wMiA8LSBmaWx0ZXIoZmluYWwuZGF0YSwgWWVhciA+PSAxOTUwICYgWWVhciA8PSAyMDE4KQ0KDQpwIDwtIGdncGxvdChkYXRhID0gY29tcDIsIG1hcHBpbmcgPSBhZXMoeCA9IEluY29tZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBMaWZlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IHBvcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gQ291bnRyeQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMC41LCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZCgpICsgICAgICAjIGNvbG9yIHBhbGxldHMgDQogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDIsIDEyKSkgKw0KICBzY2FsZV94X2xvZzEwKCkgKw0KICBsYWJzKHRpdGxlID0gJ1llYXI6IHtmcmFtZV90aW1lfScsDQogICAgICAgeCA9ICdJbmNvbWUnLA0KICAgICAgIHkgPSAnbGlmZSBleHBlY3RhbmN5JykgKw0KICB0cmFuc2l0aW9uX3RpbWUoYXMuaW50ZWdlcihZZWFyKSkgKw0KICBlYXNlX2FlcygnbGluZWFyJykNCg0KYW5pbWF0ZShwLCByZW5kZXJlciA9IGdpZnNraV9yZW5kZXJlcigpLA0KICAgICAgICAgIHJld2luZCA9IFRSVUUpDQoNCg0KDQpgYGANCg0KIyMgY29tcDMNCg0KYGBge3J9DQoNCmRmIDwtIHJlYWQuY3N2KCJEOi9PbmVEcml2ZSAtIFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBBL0RvY3VtZW50cy9TcHJpbmcnMjIvU1RBNTUzLURhdGFWaXovZ2l0L0RhdGFzZXRzL1BPQy5jc3YiKQ0KZGYyIDwtIGhlYWQoZGYsNTAwKQ0KZGYzIDwtIHNhbXBsZV9uKGRmLCA1MDApDQojIGdlbyBzdHlsaW5nDQpib3JkZXJzIDwtIGxpc3QoY29sb3IgPSB0b1JHQigicmVkIikpDQpnIDwtIGxpc3QoICAgICAgc2NvcGUgPSAndXNhJywNCiAgICAgICAgICAgcHJvamVjdGlvbiA9IGxpc3QodHlwZSA9ICdhbGJlcnMgdXNhJyksDQogICAgICAgICAgICAgc2hvd2xhbmQgPSBUUlVFLA0KICAgICAgICAgICAgbGFuZGNvbG9yID0gdG9SR0IoImdyYXk5NSIpLA0KICAgICAgICAgc3VidW5pdGNvbG9yID0gdG9SR0IoImdyYXk4NSIpLA0KICAgICAgICAgY291bnRyeWNvbG9yID0gdG9SR0IoIlJlZCIpLA0KICAgICAgICAgY291bnRyeXdpZHRoID0gMi41LA0KICAgICAgICAgc3VidW5pdHdpZHRoID0gNS41DQogICAgICAgKQ0KIyMjDQpmaWcgPC0gcGxvdF9nZW8oZGYzLCB4ID0gfnhjb29yZCwgeSA9IH55Y29vcmQpICU+JSANCiAgYWRkX21hcmtlcnMoIHRleHQgPSB+cGFzdGUoWCwgcGFzdGUoIlN0YXRlOiAiLFNUQVRFKSwgcGFzdGUoIkNvdW50eTogIixjb3VudHkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiQWRkcmVzczogIixBRERSRVNTKSwgcGFzdGUoIlpJUCBjb2RlOiAiLFpJUG5ldyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICNwYXN0ZSgiQXJyaXZhbHM6IiwgY250KSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICI8YnI+IiksDQogICAgICAgICAgICAgIGNvbG9yID0gfmRlc2NyaXB0aW9uLCANCiAgICAgICAgICAgICAgc3ltYm9sID0gImNpcmNsZSIsIA0KICAgICAgICAgICAgICBzaXplID0gflpJUFBPQywgDQogICAgICAgICAgICAgIGhvdmVyaW5mbyA9ICJ0ZXh0IikgICAlPiUgDQogIGNvbG9yYmFyKHRpdGxlID0gIlVyYmFuL1J1cmFsPGJyPjIiKSAgJT4lDQogIG1hcmtlciA9IGxpc3QobGluZSA9IGJvcmRlcnMpICU+JQ0KICBsYXlvdXQoIHRpdGxlID0gJ1VyYmFuL1J1cmFsIEdhcyBTdGF0aW9ucyBpbiB0aGUgVVMnLCANCiAgICAgICAgICBnZW8gPSBnICkNCg0KZmlnDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQpkZi5zcGxpdCA8LSBzcGxpdChkZiwgZGYkU1RBVEUpDQpkZi5saXN0IDwtIGxhcHBseShkZi5zcGxpdCwgZnVuY3Rpb24oeCkgew0KICAgICAgICAgICAgICAgICAgIHkgPC0geFtzYW1wbGUobnJvdyh4KSwgMTApLCBdDQogICAgICAgICAgICAgICAgICAgcmV0dXJuKHkpDQogICAgICAgICAgICAgICAgfSkNCnJlc3VsdCA8LSB1bnNwbGl0KGRmLmxpc3QsIGYgPSBkZiRTVEFURSwgZHJvcCA9IFRSVUUpDQoNCg0KYGBgDQoNCg0KDQoNCg0KDQoNCg0K